using AutoMapper;
using B.S.BaseData.Domain.Entities;
using B.S.BaseData.ErrorCode.ErrorCodes;
using B.S.BaseData.ErrorCode;
using B.S.BaseData.Infrastructure.Interfaces;
using B.S.BaseData.ReadAPI.Applications.Commands.Users;
using B.S.BaseData.ReadAPI.Dtos.Users;
using B.S.BaseData.ReadAPI.Utils;
using MediatR;
using Microsoft.Extensions.Logging;
using System;
using System.Threading;
using System.Threading.Tasks;
using MD5Hash;

namespace B.S.BaseData.ReadAPI.Applications.Handlers.Users
{
    /// <summary>
    /// 登录命令处理器
    /// </summary>
    public class LoginHandler : IRequestHandler<LoginCommand, ApiResult<LoginResponseDto>>
    {
        private readonly ILogger<LoginHandler> _logger;
        private readonly IUserRepository userRep;
        private readonly IMapper mapper;
        private readonly IConfiguration configuration;
        private readonly TokenHelper token;
        private readonly IUserRoleRepository userRole;

        public LoginHandler(ILogger<LoginHandler> logger, IUserRepository userRep, IMapper mapper, IConfiguration configuration, TokenHelper token, IUserRoleRepository userRole)
        {
            this._logger = logger;
            this.userRep = userRep;
            this.mapper = mapper;
            this.configuration = configuration;
            this.token = token;
            this.userRole = userRole;
        }

        public async Task<ApiResult<LoginResponseDto>> Handle(LoginCommand request, CancellationToken cancellationToken)
        {
            try
            {
                // TODO: 实现实际的登录逻辑，包括：
                // 1. 验证用户名和密码
                var user = await userRep.GetAsync(x => x.UserName == request.LoginDto.UserName||x.Phone==request.LoginDto.Phone);

                if (user == null) return ApiResult<LoginResponseDto>.Fail("用户不存在", StatusCodeEnum.Fail);
                var pwd = request.LoginDto.Password.GetMD5();
                if (user.Password.ToLower() != pwd.ToLower()) return ApiResult<LoginResponseDto>.Fail("密码错误", StatusCodeEnum.Fail);
                //转换类型
                var loginResponseDto = mapper.Map<LoginResponseDto>(user);
                // 获取用户角色列表
                var userrole = userRole.GetAll().Where(x => x.UserId == user.UserId);
                //该用户的角色ID
                var ids = userrole.Select(x => x.RoleId).ToList();
                //以,分隔的字符串形式存储角色ID 
                loginResponseDto.RoleId = string.Join(",",ids);
                //  生成JWT Token
                loginResponseDto.Token = token.CreateJwtToken(loginResponseDto);

            
                // 3. 返回登录结果
                return ApiResult<LoginResponseDto>.Success(loginResponseDto, StatusCodeEnum.Ok);

            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "登录失败");
                throw;
            }
        }
    }
}